package com.dyh.quickdemozwei;

import co.paralleluniverse.fibers.*;

import co.paralleluniverse.fibers.httpclient.FiberHttpClientBuilder;
import co.paralleluniverse.strands.SuspendableCallable;
import com.dyh.quickdemozwei.util.HttpClientCustom;
import com.dyh.quickdemozwei.util.HttpClientWrap;
import com.dyh.quickdemozwei.util.HttpClinetCallRecipes;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import org.springframework.util.StopWatch;


import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutionException;

@Slf4j
public class TestQuasar {
    HttpClientWrap httpClientWrap = new HttpClientWrap(new HttpClientCustom());

    private FiberScheduler scheduler =
            new FiberForkJoinScheduler("dyh-FiberScheduler", 1, null, false);
    @Test
    public void testCallHttp() {

        callNode1();
    }


    @Suspendable
    public String callNode1S() {
       return callNode1();
    }

    public String callNode1() {
//        StopWatch stopWatch = new StopWatch();
//        stopWatch.start();
        long start = System.currentTimeMillis();
        Map<String, Object> body = new HashMap<>();
        String url = "http://localhost:4001/one";
        String raw = HttpClinetCallRecipes.postJs(url, httpClientWrap.client(), body);
//        stopWatch.stop();
//        log.info("{}",stopWatch.prettyPrint());
        long end = System.currentTimeMillis();
        log.info("{}耗时 {}",Thread.currentThread().getName(), end - start);

        return raw;
    }

    public String callNodeWithFiber() {
//        StopWatch stopWatch = new StopWatch();
//        stopWatch.start();
        long start = System.currentTimeMillis();


        String raw = null;
        try {
            HttpResponse   httpResponse = fiberClient.execute(new HttpGet("http://localhost:4001/one"));
            HttpEntity entity = httpResponse.getEntity();
             raw = EntityUtils.toString(entity, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();

        log.info("{}耗时 {}",Thread.currentThread().getName(), end - start);
        return raw;
    }

    int concurrencyLevel = 16;
    final CloseableHttpClient fiberClient = FiberHttpClientBuilder.
            create(1). // use  io threads
            setMaxConnPerRoute(concurrencyLevel).
            setMaxConnTotal(concurrencyLevel).build();


//    public void callNode1Type2(Object obj) {
////        StopWatch stopWatch = new StopWatch();
////        stopWatch.start();
//        long start = System.currentTimeMillis();
//        Map<String, Object> body = new HashMap<>();
//        String url = "http://localhost:4001/one";
//        String raw = HttpClinetCallRecipes.postJs(url, httpClientWrap.client(), body);
////        stopWatch.stop();
////        log.info("{}",stopWatch.prettyPrint());
//        long end = System.currentTimeMillis();
//        log.info("耗时 {}", end - start);
//
//        obj = raw;
//    }

    @Test public void testInterupt() throws InterruptedException {

        Object[] objs = new Object[1];
        Thread t1 = new Thread(()->{

            objs[0]= callNode1();
//            try{
//
//            }
//            catch (InterruptedException ex){
//                log.info("被打断");
//            }
        });
        t1.start();

        Thread.sleep(500L);
        t1.interrupt();
        log.info("500ms后值={}",objs[0]);

        t1.join();
        log.info("join后值={}",objs[0]);
        System.out.println();
    }

    @Test
    public void testCallWitchC() {
        int n = 16;

        List<Fiber<String>> fibers = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int finalI = i;
            Fiber<String> fiber = new Fiber<>("name", scheduler, () -> {
                log.info("{} 开始 i={}", Thread.currentThread().getName(), finalI);

                String res = callNodeWithFiber();
//                callNode1();
//                Fiber.sleep(2000L);
//                callNode1S();
//                Fiber.sleep(2000L);
                log.info("{} 结束 i={}", Thread.currentThread().getName(), finalI);

                return String.format("%s#%s",finalI,res);
            });
            fiber.start();
            fibers.add(fiber);
        }
        for (Fiber<String> fiber : fibers) {
            try {
                Object res = fiber.get();
                log.info("res={}", res);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }


}
